-
Notifications
You must be signed in to change notification settings - Fork 117
Add option to fetch lightweight objects to reduce app hangs #15774
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@jaclync I could not see the warnings regarding the product list as you reported, so could you please verify if this PR fixes that for you? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.

I can see the I/O warning too. I guess that's because there are still code paths utilizing the "heavy" version of the toReadOnly
. Putting print
logs both into the toReadOnly
and toLightweightReadOnly
for Product
and Order
correspondingly reveal that the old method is still extensively used.
Mostly I see it in Order List tab.

I logged timings both for the heavy and lightweight readonly conversion. Looks like the light version works roughly ~10x faster. Is it a good trade-off for the fact that the "light" stripped down versions are the same "plain" objects, but just not containing relationships, and it's quite easy to treat them as complete objects and misuse them.
I wonder if we could also go for a more fundamental refactoring and make the toReadOnly
conversion completely async, i.e. obtaining a Core Data object by NSManagedObjectID
from a private context, doing conversion in a background and returning the result since the plain object is thread-safe? Though I doubt that we can afford it at the moment.
Thank you @RafaelKayumov for the review.
I understand the concern. From my POV, this is similar to having a separate model that is used for list view versus a full model for a details screen. It's up to the developers to decide which to use and test their work.
This is one of the options that @jaclync proposed when she reported WOOMOB-619. I agree that it seems to be a more reliable solution, but it comes with the complexities of handling asynchronous logic, and requires refactoring how we use fetched objects all around the app. I'd prefer keeping the logic synchronous to be more expectable and easier to maintain. Moreover, it seems like a waste of resources to try to get all the properties where they are not needed, so I chose the solution in this PR instead.
Thanks for catching this! I didn't see the warning on my side. Added a change to the order cells to use the lightweight version of the objects in c65ddb4. Could you try again and see if the warning goes away? |
Thanks for taking the time to improve the performance here – the 10x improvement sounds significant.
@itsmeichigo @RafaelKayumov I share this concern, because we've had similar problems with partially populated orders in the past. That time it happened because there were different In this PR, we stop handling order metadata ( With more AI-written code going in to the app, the chances of these kinds of errors increases too. Sure, testing our own work is important, but compiler safety is a better and stronger way to keep the app correct.
That's a good analogy – but could we actually do that, instead of sending a half-empty full model? e.g.
That way developers would be choosing a particular model that was needed, and forced to upgrade to the full model when they need it. |
Thank you for your comment @joshheald. Given the concerns you shared, do you think it's better/safer to revert the changes in this PR and go through that new object route? Or can I/someone else follow up with a separate PR which is likely to be merged after 22.7 due to other priorities? |
It's safer to revert, IMO; keeping the app working comes ahead of improving performance, so that's what I'd do. However, it's your call, see what fits in best with your work and whether you think the risk is tolerable for a release cycle. If you think you won't get it changed before 22.8, I'd definitely encourage you to revert this now. If it's the best way, you can always put it back when you have more time... |
Thanks for working on this, apology for not getting to this PR yesterday with a lot to catch up from AFK.
This is what I had in mind when writing the issue as one of the potential solutions, a different struct with just the fields needed for the list view, instead of the full Product/Order struct with relationships not used in the list view. I agree that reusing the same struct and partially populating could cause unexpected issues and there is no easy way to know if it's the full version. |
Closes WOOMOB-619
Description
There have been warnings from Xcode about performing I/O on the main thread causing app hangs. Xcode Organizer also shows reports about app hangs related to this:
The stack traces point to
ResultsController.fetchedObjects
andResultsController.object(at:)
, which then triggeredProduct.toReadOnly()
andOrder.toReadOnly
in different areas of the app. These are heavy objects with complicated relationships that require multiple trips to the database file to fetch all data. Since we're doing all the fetches on the main thread, fetching multiple such heavy objects can cause app hangs.This PR attempts to mitigate the issue by introducing the option to fetch lightweight objects - i.e., fetching objects without populating all their relationships. These are helpful for list views and other scenarios when it's not necessary to retrieve all the details of objects. This reduces the overhead of loading objects and thus minimizes app hangs.
Updated areas (following reports on Xcode Organizer and Xcode warnings):
OrderDetailsDataSource.reloadSections()
OrderDetailsViewModel.localRequirementsForShippingLabelsAreFulfilled()
OrderListViewModel.hasAnyPublishedProducts
WooShippingItemsDataSource
Testing steps
Confirm that you can no longer see warnings about performing I/O on the main thread on Xcode while running the following test cases. It's not predictable when Xcode shows the app hang warnings, so we may need to wait for app hang reports after releasing the app. For now, we can do regression testing to ensure that the app works correctly with the new changes.
TC1: Loading order details
TC2: Shipping Labels
TC3: Test order entrypoint
TC4: Blaze campaign creation form
TC5: Dashboard order count
TC6: Product list
Testing information
Screenshots
No UI changes.
RELEASE-NOTES.txt
if necessary.